package com.jy.api.okhttp;

import com.google.common.collect.Maps;
import com.jy.api.misc.dto.ISTTR4QueryDto;
import com.jy.api.misc.dto.QuHuaDMDto;
import com.jy.api.misc.dto.ShuJuYuanDto;
import com.jy.api.misc.dto.WSSYBMXTDaiMaDto;
import com.jy.api.misc.dto.ZhiJiCXDto;
import com.jy.api.misc.dto.ZhiYuDto;
import com.jy.api.misc.dto.ZhiYuMXCXDto;
import com.jy.api.misc.dto.ZhiYuYSMXDto;
import com.jy.framework.base.entity.Result;
import com.jy.rhin.config.MiscConfig;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;

/**
 * 值域术语 实现客户端
 *@className(类名称):  MiscClient 
 *@description(类描述):  
 *@author(创建人):  zsh 
 *@createDate(创建时间):  2024年8月6日 下午2:13:47
 *@updateUser(修改人):  zsh 
 *@updateDate(修改时间):  2024年8月6日 下午2:13:47
 *@updateRemark(修改备注):   
 *@version(版本):  v1.0
 */
@Slf4j
@Component("MiscClient")
public class MiscClient extends AbstractThirdClient {

    @Autowired
    private MiscConfig miscConfig;

    public MiscClient(@Qualifier("okHttpTemplate") RestTemplate restTemplate) {
        super(restTemplate);
    }

    public MiscConfig getMiscConfig() {
		return miscConfig;
	}

	public void setMiscConfig(MiscConfig miscConfig) {
		this.miscConfig = miscConfig;
	}

    @Override
    public String name() {
        return "MiscClient";
    }

    /**
	 * 查询集值映射 IST-TR4
	 * @param req
	 * @return
	 */
	public Result<List<ZhiYuYSMXDto>> jiZhiYSCX(ISTTR4QueryDto req) {
		String url = miscConfig.getUrl().getSelectTR4Path();

		String param = JSONUtil.toJsonStr(JSONUtil.parseObj(req));
		log.debug("发起远程http查询集值映射 IST-TR4：{}=>{}", url, param);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.POST, MediaType.APPLICATION_JSON, param, Maps.newHashMap());
		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http查询集值映射 IST-TR4：{}", message);
			return Result.fail(message);
		}
		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONArray jsonArray = jsonObject.getJSONArray("data");
		List<ZhiYuYSMXDto> list = JSONUtil.toList(jsonArray, ZhiYuYSMXDto.class);
		return Result.success(list);
	}
	

	/**
	 * 获取集值映射 IST-TR3
	 * @param id 唯一标识符
	 * @return
	 */
	public Result<ZhiYuYSMXDto> jiZhiYSHQ(String id) {
		String url = miscConfig.getUrl().getFindTR3Path();
		log.info("发起远程http获取集值映射 IST-TR3：{}=>{}", url, id);
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("id", id);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http获取集值映射 IST-TR3：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONObject data = jsonObject.getJSONObject("data");
		ZhiYuYSMXDto dto = JSONUtil.toBean(data, ZhiYuYSMXDto.class);
		return Result.success(dto);
	}
    
    
    /**
     * 查询值集 IST-TR2
     * @param req
     * @return
     */
    public Result<List<ZhiYuDto>> jiZhiCX(ZhiJiCXDto req){
    	String url = miscConfig.getUrl().getSelectTR2Path();

		String param = JSONUtil.toJsonStr(JSONUtil.parseObj(req));
		log.debug("发起远程http查询值集 IST-TR2：{}=>{}", url, param);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.POST, MediaType.APPLICATION_JSON, param, Maps.newHashMap());
		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http查询值集 IST-TR2：{}", message);
			return Result.fail(message);
		}
		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONArray jsonArray = jsonObject.getJSONArray("data");
		List<ZhiYuDto> list = JSONUtil.toList(jsonArray, ZhiYuDto.class);
		return Result.success(list);
    }
    
    
    /**
     * 获取值集 IST-TR1
     * @param id 唯一标识符
     * @return
     */
    public Result<WSSYBMXTDaiMaDto> jiZhiHQ(String id){
    	String url = miscConfig.getUrl().getFindTR1Path();
		log.info("发起远程http获取值集 IST-TR1：{}=>{}", url, id);
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("id", id);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http获取值集 IST-TR1：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONObject data = jsonObject.getJSONObject("data");
		WSSYBMXTDaiMaDto dto = JSONUtil.toBean(data, WSSYBMXTDaiMaDto.class);
		return Result.success(dto);
    }
    
    
    /**
     * 根据值域标识符获取代码
     * @param zhiJiBSF 值域标识符
     * @return
     */
    public Result<WSSYBMXTDaiMaDto> getDaiMaByZJBSF(String zhiJiBSF){
    	String url = miscConfig.getUrl().getFindByIdentifierPath();
		log.info("发起远程http根据值域标识符获取代码：{}=>{}", url, zhiJiBSF);
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("zhiJiBSF", zhiJiBSF);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http根据值域标识符获取代码：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONObject data = jsonObject.getJSONObject("data");
		WSSYBMXTDaiMaDto dto = JSONUtil.toBean(data, WSSYBMXTDaiMaDto.class);
		return Result.success(dto);
    }
    
    
    
    /**
     * 根据值域标识符和code获取value
     * @param dto
     * @param mode
     * @return
     */
    public Result<List<WSSYBMXTDaiMaDto>> getValueByCode(ZhiYuMXCXDto[] dto, Integer mode){
    	String url = miscConfig.getUrl().getSelectByIdeAndCodePath();
		String param = JSONUtil.toJsonStr(JSONUtil.parseArray(dto));
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("mode", mode);
		log.debug("发起远程http根据值域标识符和code获取value：{}=>{}", url, param);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.POST, MediaType.APPLICATION_JSON, param, uriVariables);
		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http根据值域标识符和code获取value：{}", message);
			return Result.fail(message);
		}
		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONArray jsonArray = jsonObject.getJSONArray("data");
		List<WSSYBMXTDaiMaDto> list = JSONUtil.toList(jsonArray, WSSYBMXTDaiMaDto.class);
		return Result.success(list);
    }
    
    
    
   /**
    * 根据值域标识符获取代码（列表）
    * @param zhiJiBSFList 值域标识符集合
    * @return
    */
    public Result<List<WSSYBMXTDaiMaDto>> getDaiMaByZJBSFList(String[] zhiJiBSFList){
    	String url = miscConfig.getUrl().getSelectByIdentifierListPath();
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("zhiJiBSFList", zhiJiBSFList);
		log.debug("发起远程http根据值域标识符获取代码（列表）：{}=>{}", url, zhiJiBSFList);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);
		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http根据值域标识符获取代码（列表）：{}", message);
			return Result.fail(message);
		}
		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONArray jsonArray = jsonObject.getJSONArray("data");
		List<WSSYBMXTDaiMaDto> list = JSONUtil.toList(jsonArray, WSSYBMXTDaiMaDto.class);
		return Result.success(list);
    }
    
    
    
    /**
     * 获取区划代码
     * @param quHuaDM
     * @return
     */
    public Result<QuHuaDMDto> getQuHuaDMByDM(String quHuaDM){    	
    	String url = miscConfig.getUrl().getFindDCodeByIdentifierPath();
		log.info("发起远程http获取区划代码：{}=>{}", url, quHuaDM);
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("quHuaDM", quHuaDM);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http获取区划代码：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONObject data = jsonObject.getJSONObject("data");
		QuHuaDMDto dto = JSONUtil.toBean(data, QuHuaDMDto.class);
		return Result.success(dto);
    }
    
    
    
    /**
     * 根据值域标识符判断是否存在该值域
     * @param zhiJiBSF 值域标识符
     * @param zhi 值
     * @return
     */
    public Result<Boolean> zhiYuSFCZ(String zhiJiBSF, String zhi){
    	String url = miscConfig.getUrl().getGetExistByRangePath();
		
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("zhiJiBSF", zhiJiBSF);
		uriVariables.put("zhi", zhi);
		log.info("发起远程http根据值域标识符判断是否存在该值域：{}=>{}", url, JSONUtil.parseObj(uriVariables));
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http根据值域标识符判断是否存在该值域：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		Boolean flag = jsonObject.getBool("data");
		return Result.success(flag);
    }

    
    
    /**
     * 根据编码系统标识符及值、值含义判断值是否在编码系统中存在
     * @param biaoShiFu 标识符
     * @param zhi 值
     * @param zhiValue 值含义
     * @return
     */
    public Result<Boolean> bianMaXTZhiExist(String biaoShiFu, String zhi, String zhiValue){
    	String url = miscConfig.getUrl().getGetExistByEncodePath();
		
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("biaoShiFu", biaoShiFu);
		uriVariables.put("zhi", zhi);
		uriVariables.put("zhiValue", zhiValue);
		log.info("发起远程http根据编码系统标识符及值、值含义判断值是否在编码系统中存在：{}=>{}", url, JSONUtil.parseObj(uriVariables));
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http根据编码系统标识符及值、值含义判断值是否在编码系统中存在：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		Boolean flag = jsonObject.getBool("data");
		return Result.success(flag);
    }
    
    
    
    /**
     * 根据标识符查看详情
     * @param biaoShiFu 标识符
     * @return
     */
    public Result<ShuJuYuanDto> getDetailByShuJuYuan(String biaoShiFu){
    	String url = miscConfig.getUrl().getFindDetailByIdentifierPath();
		log.info("发起远程http根据标识符查看详情：{}=>{}", url, biaoShiFu);
		Map<String, Object> uriVariables = Maps.newHashMap();
		uriVariables.put("biaoShiFu", biaoShiFu);
		ResponseEntity<String> responseEntity = execute(url, null, HttpMethod.GET, MediaType.APPLICATION_JSON, null, uriVariables);

		String message = this.verify(responseEntity);
		if (StringUtils.isNotBlank(message)) {
			log.error("发起远程http根据标识符查看详情：{}", message);
			return Result.fail(message);
		}

		JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
		JSONObject data = jsonObject.getJSONObject("data");
		ShuJuYuanDto dto = JSONUtil.toBean(data, ShuJuYuanDto.class);
		return Result.success(dto);
    }

    private String verify(ResponseEntity<String> responseEntity) {
        if (!super.isSuccess(responseEntity)) {
            return "请求状态不成功：" + responseEntity.getStatusCode();
        }

        String body = responseEntity.getBody();
        log.debug("response body {}", body);
        JSONObject jsonObject = JSONUtil.parseObj(body);

        String code = jsonObject.getStr("code");
        String msg = jsonObject.getStr("msg");
        if (!this.isSuccess(code)) {
            return StringUtils.join("业务状态不成功：", code, ":", msg);
        }
        return null;
    }

    private boolean isSuccess(String code) {
        return "1".equals(code);
    }

}
